<template>
  <SysDialog
    :title="dialog.title"
    :visible="dialog.visible"
    :width="dialog.width"
    :height="dialog.height"
    @onClose="onClose"
    @onConfirm="confirm"
  >
    <template v-slot:content>
      <el-form
        :model="dialogModel"
        ref="addDeptForm"
        :rules="rules"
        label-width="80px"
        size="small"
      >
        <el-row>
          <el-col :span="12">
            <el-form-item prop="parentName" label="上级部门">
              <el-input type="hidden" v-model="dialogModel.pid"></el-input>
              <el-input
                @click="selectParent"
                v-model="dialogModel.parentName"
              ></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item prop="name" label="部门名称">
              <el-input v-model="dialogModel.name"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item prop="deptCode" label="部门编码">
              <el-input v-model="dialogModel.deptCode"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item prop="deptPhone" label="部门电话">
              <el-input v-model="dialogModel.deptPhone"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item prop="manager" label="部门经理">
              <el-input v-model="dialogModel.manager"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item prop="deptAddress" label="部门地址">
              <el-input v-model="dialogModel.deptAddress"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item prop="orderNum" label="部门序号">
              <el-input v-model="dialogModel.orderNum"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </template>
  </SysDialog>
  <parentVue ref="parentRef" @select="select"></parentVue>
</template>
<script setup lang="ts">
import { ref, reactive, nextTick } from 'vue'
// 引入通用的弹框组件
import SysDialog from '@/components/SysDialog.vue'
// 引入对弹框组件的操作，打开和关闭，dialog的一些属性设置
import useDialog from '@/hooks/useDialog'
// 编辑类型和标题的枚举类型，这个文件可以用来熟悉枚举的用法，但是可以省略
import { EditType, Title } from '@/type/BaseEnum'
// 引入对于form表单进行操作需要的数据和校验规则
import useBaseModel from '@/composables/department/useBaseModel'
// 引入选择父菜单的弹框
import parentVue from './parent.vue'
// 引入选择父级的操作方法
import useSelectParent from '@/composables/department/useSelectParent'
// 引入需要的类型声明文件
import { DeptModel, SelectNode } from '@/api/dept/DeptModel'
import { ElForm } from 'element-plus'
import useInstance from '@/hooks/useInstance'

// 全局挂载组件
const { global, proxy } = useInstance()

// onShow是为了用作触发事件，和onClose，onConfirm用法不一样
// 同时这个onConfirm由于是直接在子组件定义好的事件，内容不能更改
// 所以为了在关闭时添加一些其他的操作，一般回不使用这个事件
const { dialog, onClose, onShow, onConfirm } = useDialog()

//基础数据，form对话框绑定的数据和验证的规则
const { dialogModel, rules } = useBaseModel()
// 获取组组建，用来做表单验证
const addDeptForm = ref<InstanceType<typeof ElForm>>()
// 声明事件save，就是保存的事件，把这个事件传递给父组件
const emit = defineEmits(['save'])
// 不使用子组件内定义好的事件，因为需要处理其他内容
const confirm = () => {
  addDeptForm.value?.validate(valid => {
    if (valid) {
      emit('save', dialogModel)
      onClose()
    }
  })
}
// 这个show的使用是在useDept文件中触发的，这个useDept文件是和机构管理这根组件平级的
// 所以这个show其实就是在子组件中定义的事件，然后需要在父组件中触发
// 在2中父组件调用子组件中定义的方法，使用的是ref属性，如下所示
// clickParent() {
//   this.$refs.mychild.parentHandleclick("嘿嘿嘿");
// }
// 但是在3中，组件的写法中没有默认的export default { name:  data: }等一大堆的东西
// 所以如何才能让父组件可以读取子组件的事件？
// 需要在子组件中先把它暴露出去，就需要使用defineExpose
// 然后在父组件中通过ref就可以控制它了,这里就是使用的方式
//   const addBtn = () => {
//   addDeptRef.value?.show(EditType.ADD)
// }
// 但是传递还有一个问题就是需要给他传递出去，包括ref的获取
//  const addDeptRef = ref<{ show: (type: string, row?: DeptModel) => void }>()
// 这样在设置这个ref值的时候，同时获取它的show方法，就可以直接调用了
// 因为需要回显数据，所以在调用show方法的时候，还需要接收原来的数据
// 这个参数是在调用的时候传入的实际参数，这里是定义方法，调用方法是在useDept文件
const show = (type: string, row?: DeptModel) => {
  console.log('调用弹窗')
  dialog.height = 200
  // 设置弹框的标题
  type == EditType.ADD
    ? (dialog.title = Title.ADD)
    : (dialog.title = Title.EDIT)
  onShow()
  // 清空表单
  global.$resetForm(addDeptForm.value, dialogModel)
  if (EditType.EDIT === type) {
    nextTick(() => {
      global.$objCoppy(row, dialogModel)
    })
  }
  dialogModel.type = type
}

defineExpose({
  show
})

// 选择上级部门弹出框的操作文件
// 一个是ref值，另一个是点击事件，就是触发弹出框的show事件
// 其实就是通过selectParent这个事件来触发子组件的show,这里也是通过parentRef来触发了selectParent
// 这个事件,相当于是调用了这个文件,生成一个ref对象,然后通过这个对象,调用了子组件内部的事件
const { parentRef, selectParent } = useSelectParent()
// 这个是子组件内部注册的emit事件,包括传递的值
const select = (node: SelectNode) => {
  console.log('父组件取到值')
  console.log(node)
  dialogModel.pid = node.id
  dialogModel.parentName = node.name
}
</script>
<style scoped lang="scss"></style>
